Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

[core] Fast tileCount with help from @mapbox/sphericalmercator module #9906

Merged
merged 1 commit into from
Sep 9, 2017

Conversation

asheemmamoowala
Copy link
Contributor

Closes #9675

Implement a separate util::tileCount() method for computing the number of tiles that need to be downloaded for offline packs.

The time for computing tile count for a bounding box around SF went from 12070 ms to 1 ms.

The failed attempts include:

  • Running tileCover on the max zoom, and getting parents of those tiles up to min zoom. I was surprised by the cost of boost::hash_combine which made this more expensive than running tileCover for every zoom level.
  • Computing the number of tiles needed at each zoom level based on LatLng extents of the bounding box vs LatLng extents of a tile. This approached had way better performance but suffered from floating point errors due to the precision of LatLng for high zoom levels.

Thanks to @jfirebaugh for pointing me to @mapbox/sphericalmercator

@asheemmamoowala asheemmamoowala force-pushed the 9675-tile-count branch 2 times, most recently from 2fba28f to 65c1d27 Compare September 5, 2017 19:06
assert(maxZ < std::numeric_limits<uint8_t>::max());

unsigned long result = 0;;
for (auto z = minZ; z <= maxZ; z++) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

autouint8_t

@@ -43,6 +44,24 @@ std::vector<CanonicalTileID> OfflineTilePyramidRegionDefinition::tileCover(Sourc
return result;
}

unsigned long OfflineTilePyramidRegionDefinition::tileCount(SourceType type, uint16_t tileSize, const Range<uint8_t>& zoomRange) const {
double minZ = std::max<double>(util::coveringZoomLevel(minZoom, type, tileSize), zoomRange.min);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you refactor the code that's duplicated from tileCover into a function with the signature:

Range<uint8_t> coveringZoomRange(SourceType, uint16_t tileSize, const Range<uint8_t>& zoomRange) const


unsigned long result = 0;;
for (auto z = minZ; z <= maxZ; z++) {
auto count = util::tileCount(bounds, z, tileSize);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

result += util::tileCount(bounds, z, tileSize)

@@ -89,6 +89,19 @@ class Projection {
wrapMode
};
}

// Project lat, lon to point in a zoom-dependent world size
static Point<double> project(const LatLng& point, uint8_t zoom, uint16_t tileSize) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be written in terms of the existing project function, or vice versa?

@asheemmamoowala asheemmamoowala force-pushed the 9675-tile-count branch 2 times, most recently from 8ddd56a to 0d732cb Compare September 6, 2017 21:29
assert(maxZ >= 0);
assert(minZ < std::numeric_limits<uint8_t>::max());
assert(maxZ < std::numeric_limits<uint8_t>::max());
return { (uint8_t)minZ, (uint8_t)maxZ };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use static_cast rather than C-style cast.

@asheemmamoowala asheemmamoowala merged commit 50fd917 into master Sep 9, 2017
@asheemmamoowala asheemmamoowala deleted the 9675-tile-count branch September 9, 2017 00:38
@@ -18,5 +18,8 @@ int32_t coveringZoomLevel(double z, SourceType type, uint16_t tileSize);
std::vector<UnwrappedTileID> tileCover(const TransformState&, int32_t z);
std::vector<UnwrappedTileID> tileCover(const LatLngBounds&, int32_t z);

// Compute only the count of tiles needed for tileCover
unsigned long tileCount(const LatLngBounds&, uint8_t z, uint16_t tileSize);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we please use fixed width number types (like uint64_t)? Unfortunately, unsigned long is 32 bit on some and 64 bit on other platforms.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Core The cross-platform C++ core, aka mbgl
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants